{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 数据预处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/malele/anaconda3/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
      "  from ._conv import register_converters as _register_converters\n",
      "Using TensorFlow backend.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "X_train shape: (9531, 200, 12, 1)\n",
      "Y_train shape: (9531, 49)\n",
      "X_test shape: (2383, 200, 12, 1)\n",
      "Y_test shape: (2383, 49)\n"
     ]
    }
   ],
   "source": [
    "import h5py\n",
    "import numpy as np\n",
    "import tensorflow as tf \n",
    "import keras\n",
    "from keras.layers import Input, Dense, ZeroPadding2D, Dropout, Activation, BatchNormalization\n",
    "from keras.layers import Flatten, Conv2D, AveragePooling2D, MaxPooling2D, concatenate\n",
    "from keras.models import Model\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "def convert_to_one_hot(Y, C):\n",
    "    Y = np.eye(C)[Y.reshape(-1)].T\n",
    "    return Y\n",
    "\n",
    "file = h5py.File('DB2/DB2_S1_image_200_0.h5','r')\n",
    "imageData   = file['imageData'][:]\n",
    "imageLabel  = file['imageLabel'][:]  \n",
    "file.close()\n",
    "\n",
    "# 随机打乱数据和标签\n",
    "N = imageData.shape[0]\n",
    "index = np.random.permutation(N)\n",
    "data  = imageData[index,:,:]\n",
    "label = imageLabel[index]\n",
    "\n",
    "# 对数据升维,标签one-hot\n",
    "data  = np.expand_dims(data, axis=3)\n",
    "label = convert_to_one_hot(label,49).T\n",
    "\n",
    "# 划分数据集\n",
    "N = data.shape[0]\n",
    "num_train = round(N*0.8)\n",
    "X_train = data[0:num_train,:,:,:]\n",
    "Y_train = label[0:num_train,:]\n",
    "X_test  = data[num_train:N,:,:,:]\n",
    "Y_test  = label[num_train:N,:]\n",
    "\n",
    "print (\"X_train shape: \" + str(X_train.shape))\n",
    "print (\"Y_train shape: \" + str(Y_train.shape))\n",
    "print (\"X_test shape: \" + str(X_test.shape))\n",
    "print (\"Y_test shape: \" + str(Y_test.shape))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "#写一个LossHistory类，保存loss和acc\n",
    "class LossHistory(keras.callbacks.Callback):\n",
    "    def on_train_begin(self, logs={}):\n",
    "        self.losses = {'batch':[], 'epoch':[]}\n",
    "        self.accuracy = {'batch':[], 'epoch':[]}\n",
    "        self.val_loss = {'batch':[], 'epoch':[]}\n",
    "        self.val_acc = {'batch':[], 'epoch':[]}\n",
    "\n",
    "    def on_batch_end(self, batch, logs={}):\n",
    "        self.losses['batch'].append(logs.get('loss'))\n",
    "        self.accuracy['batch'].append(logs.get('acc'))\n",
    "        self.val_loss['batch'].append(logs.get('val_loss'))\n",
    "        self.val_acc['batch'].append(logs.get('val_acc'))\n",
    "\n",
    "    def on_epoch_end(self, batch, logs={}):\n",
    "        self.losses['epoch'].append(logs.get('loss'))\n",
    "        self.accuracy['epoch'].append(logs.get('acc'))\n",
    "        self.val_loss['epoch'].append(logs.get('val_loss'))\n",
    "        self.val_acc['epoch'].append(logs.get('val_acc'))\n",
    "\n",
    "    def loss_plot(self, loss_type):\n",
    "        iters = range(len(self.losses[loss_type]))\n",
    "        plt.figure()\n",
    "        # acc\n",
    "        plt.plot(iters, self.accuracy[loss_type], 'r', label='train acc')\n",
    "        # loss\n",
    "        plt.plot(iters, self.losses[loss_type], 'g', label='train loss')\n",
    "        if loss_type == 'epoch':\n",
    "            # val_acc\n",
    "            plt.plot(iters, self.val_acc[loss_type], 'b', label='val acc')\n",
    "            # val_loss\n",
    "            plt.plot(iters, self.val_loss[loss_type], 'k', label='val loss')\n",
    "        plt.grid(True)\n",
    "        plt.xlabel(loss_type)\n",
    "        plt.ylabel('acc-loss')\n",
    "        plt.legend(loc=\"upper right\")\n",
    "        plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 建立模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "__________________________________________________________________________________________________\n",
      "Layer (type)                    Output Shape         Param #     Connected to                     \n",
      "==================================================================================================\n",
      "input_1 (InputLayer)            (None, 200, 12, 1)   0                                            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_1 (Conv2D)               (None, 181, 10, 32)  1952        input_1[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_3 (Conv2D)               (None, 185, 10, 32)  1568        input_1[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_5 (Conv2D)               (None, 189, 10, 32)  1184        input_1[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_7 (Conv2D)               (None, 193, 10, 32)  800         input_1[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_1 (MaxPooling2D)  (None, 9, 10, 32)    0           conv2d_1[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_3 (MaxPooling2D)  (None, 9, 10, 32)    0           conv2d_3[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_5 (MaxPooling2D)  (None, 9, 10, 32)    0           conv2d_5[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_7 (MaxPooling2D)  (None, 9, 10, 32)    0           conv2d_7[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_2 (Conv2D)               (None, 7, 10, 64)    6208        max_pooling2d_1[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_4 (Conv2D)               (None, 6, 10, 64)    8256        max_pooling2d_3[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_6 (Conv2D)               (None, 5, 10, 64)    10304       max_pooling2d_5[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_8 (Conv2D)               (None, 4, 10, 64)    12352       max_pooling2d_7[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_2 (MaxPooling2D)  (None, 1, 10, 64)    0           conv2d_2[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_4 (MaxPooling2D)  (None, 1, 10, 64)    0           conv2d_4[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_6 (MaxPooling2D)  (None, 1, 10, 64)    0           conv2d_6[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_8 (MaxPooling2D)  (None, 1, 10, 64)    0           conv2d_8[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "flatten_1 (Flatten)             (None, 640)          0           max_pooling2d_2[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "flatten_2 (Flatten)             (None, 640)          0           max_pooling2d_4[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "flatten_3 (Flatten)             (None, 640)          0           max_pooling2d_6[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "flatten_4 (Flatten)             (None, 640)          0           max_pooling2d_8[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "concatenate_1 (Concatenate)     (None, 2560)         0           flatten_1[0][0]                  \n",
      "                                                                 flatten_2[0][0]                  \n",
      "                                                                 flatten_3[0][0]                  \n",
      "                                                                 flatten_4[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "dropout_1 (Dropout)             (None, 2560)         0           concatenate_1[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_1 (Dense)                 (None, 128)          327808      dropout_1[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "dropout_2 (Dropout)             (None, 128)          0           dense_1[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "dense_2 (Dense)                 (None, 49)           6321        dropout_2[0][0]                  \n",
      "==================================================================================================\n",
      "Total params: 376,753\n",
      "Trainable params: 376,753\n",
      "Non-trainable params: 0\n",
      "__________________________________________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "def CNN(input_shape=(200,12,1), classes=49): \n",
    "    X_input = Input(input_shape)\n",
    "    \n",
    "    f1 = [20, 16, 12, 8]\n",
    "    f2 = [3, 4, 5, 6]\n",
    "    convs = []\n",
    "    \n",
    "    for i in range(4):\n",
    "        x = Conv2D(filters=32, kernel_size=(f1[i],3), strides=(1,1), activation='relu',padding='valid')(X_input)\n",
    "        x = MaxPooling2D((20,1))(x)\n",
    "        \n",
    "        x = Conv2D(filters=64, kernel_size=(f2[i],1), strides=(1,1), activation='relu', padding='valid')(x)\n",
    "        x = MaxPooling2D((9-2-i,1))(x)\n",
    "        \n",
    "        x = Flatten()(x)\n",
    "        convs.append(x)\n",
    "        \n",
    "    merge = concatenate(convs,axis=1)\n",
    "    X = merge\n",
    "    X = Dropout(0.5)(X)\n",
    "    X = Dense(128,activation='relu')(X)\n",
    "    X = Dropout(0.5)(X)\n",
    "    X = Dense(classes, activation='softmax')(X)\n",
    "    model = Model(inputs=X_input, outputs=X)\n",
    "    return model\n",
    "    \n",
    "model = CNN()\n",
    "model.summary()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 训练原始数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 9531 samples, validate on 2383 samples\n",
      "Epoch 1/100\n",
      "9531/9531 [==============================] - 18s 2ms/step - loss: 3.5422 - acc: 0.1074 - val_loss: 2.7003 - val_acc: 0.2879\n",
      "Epoch 2/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 2.6231 - acc: 0.2702 - val_loss: 2.0154 - val_acc: 0.4171\n",
      "Epoch 3/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 2.2136 - acc: 0.3666 - val_loss: 1.6906 - val_acc: 0.5052\n",
      "Epoch 4/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.9530 - acc: 0.4281 - val_loss: 1.4669 - val_acc: 0.5665\n",
      "Epoch 5/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.7825 - acc: 0.4658 - val_loss: 1.3362 - val_acc: 0.6009\n",
      "Epoch 6/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.6651 - acc: 0.4982 - val_loss: 1.2362 - val_acc: 0.6211\n",
      "Epoch 7/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.5690 - acc: 0.5194 - val_loss: 1.1671 - val_acc: 0.6391\n",
      "Epoch 8/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.4940 - acc: 0.5370 - val_loss: 1.1177 - val_acc: 0.6601\n",
      "Epoch 9/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.4208 - acc: 0.5529 - val_loss: 1.0705 - val_acc: 0.6643\n",
      "Epoch 10/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.3870 - acc: 0.5665 - val_loss: 1.0284 - val_acc: 0.6773\n",
      "Epoch 11/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.3262 - acc: 0.5775 - val_loss: 1.0009 - val_acc: 0.6811\n",
      "Epoch 12/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.2888 - acc: 0.5905 - val_loss: 0.9623 - val_acc: 0.6991\n",
      "Epoch 13/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.2649 - acc: 0.6034 - val_loss: 0.9523 - val_acc: 0.6958\n",
      "Epoch 14/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.2358 - acc: 0.6068 - val_loss: 0.9388 - val_acc: 0.6932\n",
      "Epoch 15/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.1962 - acc: 0.6129 - val_loss: 0.8842 - val_acc: 0.7146\n",
      "Epoch 16/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.1553 - acc: 0.6289 - val_loss: 0.8566 - val_acc: 0.7209\n",
      "Epoch 17/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.1332 - acc: 0.6385 - val_loss: 0.8594 - val_acc: 0.7167\n",
      "Epoch 18/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.1137 - acc: 0.6446 - val_loss: 0.8370 - val_acc: 0.7260\n",
      "Epoch 19/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.0935 - acc: 0.6404 - val_loss: 0.8353 - val_acc: 0.7335\n",
      "Epoch 20/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.0625 - acc: 0.6518 - val_loss: 0.8227 - val_acc: 0.7394\n",
      "Epoch 21/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.0670 - acc: 0.6489 - val_loss: 0.8334 - val_acc: 0.7260\n",
      "Epoch 22/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.0495 - acc: 0.6598 - val_loss: 0.7854 - val_acc: 0.7520\n",
      "Epoch 23/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.0209 - acc: 0.6632 - val_loss: 0.7635 - val_acc: 0.7566\n",
      "Epoch 24/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 1.0083 - acc: 0.6651 - val_loss: 0.7850 - val_acc: 0.7474\n",
      "Epoch 25/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.9938 - acc: 0.6675 - val_loss: 0.7593 - val_acc: 0.7432\n",
      "Epoch 26/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.9916 - acc: 0.6722 - val_loss: 0.7707 - val_acc: 0.7545\n",
      "Epoch 27/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.9679 - acc: 0.6821 - val_loss: 0.7400 - val_acc: 0.7499\n",
      "Epoch 28/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.9407 - acc: 0.6861 - val_loss: 0.7291 - val_acc: 0.7558\n",
      "Epoch 29/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.9427 - acc: 0.6830 - val_loss: 0.7225 - val_acc: 0.7574\n",
      "Epoch 30/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.9212 - acc: 0.6977 - val_loss: 0.7309 - val_acc: 0.7558\n",
      "Epoch 31/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.9229 - acc: 0.6943 - val_loss: 0.7248 - val_acc: 0.7658\n",
      "Epoch 32/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.9130 - acc: 0.6931 - val_loss: 0.7142 - val_acc: 0.7654\n",
      "Epoch 33/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.8969 - acc: 0.7012 - val_loss: 0.7092 - val_acc: 0.7705\n",
      "Epoch 34/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.8974 - acc: 0.6981 - val_loss: 0.7080 - val_acc: 0.7667\n",
      "Epoch 35/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.8943 - acc: 0.7027 - val_loss: 0.6941 - val_acc: 0.7667\n",
      "Epoch 36/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.8591 - acc: 0.7127 - val_loss: 0.6909 - val_acc: 0.7684\n",
      "Epoch 37/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.8591 - acc: 0.7094 - val_loss: 0.7000 - val_acc: 0.7734\n",
      "Epoch 38/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.8532 - acc: 0.7122 - val_loss: 0.7103 - val_acc: 0.7558\n",
      "Epoch 39/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.8495 - acc: 0.7128 - val_loss: 0.6848 - val_acc: 0.7742\n",
      "Epoch 40/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.8308 - acc: 0.7194 - val_loss: 0.6842 - val_acc: 0.7709\n",
      "Epoch 41/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.8229 - acc: 0.7197 - val_loss: 0.6873 - val_acc: 0.7696\n",
      "Epoch 42/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.8147 - acc: 0.7264 - val_loss: 0.6736 - val_acc: 0.7835\n",
      "Epoch 43/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.8063 - acc: 0.7299 - val_loss: 0.6693 - val_acc: 0.7797\n",
      "Epoch 44/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.8091 - acc: 0.7229 - val_loss: 0.6612 - val_acc: 0.7763\n",
      "Epoch 45/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7983 - acc: 0.7268 - val_loss: 0.6641 - val_acc: 0.7784\n",
      "Epoch 46/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7909 - acc: 0.7298 - val_loss: 0.6469 - val_acc: 0.7898\n",
      "Epoch 47/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7891 - acc: 0.7285 - val_loss: 0.6455 - val_acc: 0.7889\n",
      "Epoch 48/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7875 - acc: 0.7307 - val_loss: 0.6491 - val_acc: 0.7885\n",
      "Epoch 49/100\n",
      "9531/9531 [==============================] - 16s 2ms/step - loss: 0.7799 - acc: 0.7323 - val_loss: 0.6360 - val_acc: 0.7898\n",
      "Epoch 50/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7507 - acc: 0.7432 - val_loss: 0.6353 - val_acc: 0.7856\n",
      "Epoch 51/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7492 - acc: 0.7403 - val_loss: 0.6551 - val_acc: 0.7835\n",
      "Epoch 52/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7607 - acc: 0.7413 - val_loss: 0.6441 - val_acc: 0.7910\n",
      "Epoch 53/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7548 - acc: 0.7408 - val_loss: 0.6588 - val_acc: 0.7847\n",
      "Epoch 54/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7450 - acc: 0.7489 - val_loss: 0.6479 - val_acc: 0.7839\n",
      "Epoch 55/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7434 - acc: 0.7484 - val_loss: 0.6533 - val_acc: 0.7851\n",
      "Epoch 56/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7220 - acc: 0.7527 - val_loss: 0.6484 - val_acc: 0.7885\n",
      "Epoch 57/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7084 - acc: 0.7583 - val_loss: 0.6339 - val_acc: 0.7898\n",
      "Epoch 58/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7381 - acc: 0.7461 - val_loss: 0.6339 - val_acc: 0.7864\n",
      "Epoch 59/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7310 - acc: 0.7509 - val_loss: 0.6354 - val_acc: 0.7923\n",
      "Epoch 60/100\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7110 - acc: 0.7538 - val_loss: 0.6343 - val_acc: 0.7940\n",
      "Epoch 61/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7225 - acc: 0.7582 - val_loss: 0.6258 - val_acc: 0.7885\n",
      "Epoch 62/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.7165 - acc: 0.7592 - val_loss: 0.6116 - val_acc: 0.7986\n",
      "Epoch 63/100\n",
      "9531/9531 [==============================] - 16s 2ms/step - loss: 0.7139 - acc: 0.7558 - val_loss: 0.6497 - val_acc: 0.7801\n",
      "Epoch 64/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6795 - acc: 0.7626 - val_loss: 0.6150 - val_acc: 0.8019\n",
      "Epoch 65/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6992 - acc: 0.7589 - val_loss: 0.6221 - val_acc: 0.7965\n",
      "Epoch 66/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6929 - acc: 0.7598 - val_loss: 0.6158 - val_acc: 0.8049\n",
      "Epoch 67/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6809 - acc: 0.7634 - val_loss: 0.6462 - val_acc: 0.7944\n",
      "Epoch 68/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6846 - acc: 0.7661 - val_loss: 0.6141 - val_acc: 0.7973\n",
      "Epoch 69/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6829 - acc: 0.7694 - val_loss: 0.6330 - val_acc: 0.7969\n",
      "Epoch 70/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6680 - acc: 0.7685 - val_loss: 0.6257 - val_acc: 0.7927\n",
      "Epoch 71/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6565 - acc: 0.7758 - val_loss: 0.6488 - val_acc: 0.7923\n",
      "Epoch 72/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6682 - acc: 0.7689 - val_loss: 0.6202 - val_acc: 0.7944\n",
      "Epoch 73/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6659 - acc: 0.7659 - val_loss: 0.6146 - val_acc: 0.7961\n",
      "Epoch 74/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6686 - acc: 0.7695 - val_loss: 0.6264 - val_acc: 0.8061\n",
      "Epoch 75/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6488 - acc: 0.7720 - val_loss: 0.6199 - val_acc: 0.8057\n",
      "Epoch 76/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6551 - acc: 0.7731 - val_loss: 0.6062 - val_acc: 0.7998\n",
      "Epoch 77/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6524 - acc: 0.7730 - val_loss: 0.6329 - val_acc: 0.8078\n",
      "Epoch 78/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6414 - acc: 0.7717 - val_loss: 0.6043 - val_acc: 0.8028\n",
      "Epoch 79/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6411 - acc: 0.7754 - val_loss: 0.6311 - val_acc: 0.7998\n",
      "Epoch 80/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6428 - acc: 0.7788 - val_loss: 0.6082 - val_acc: 0.8078\n",
      "Epoch 81/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6287 - acc: 0.7848 - val_loss: 0.6215 - val_acc: 0.8032\n",
      "Epoch 82/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6220 - acc: 0.7825 - val_loss: 0.6295 - val_acc: 0.8019\n",
      "Epoch 83/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6351 - acc: 0.7803 - val_loss: 0.6051 - val_acc: 0.8040\n",
      "Epoch 84/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6323 - acc: 0.7862 - val_loss: 0.6015 - val_acc: 0.8095\n",
      "Epoch 85/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6167 - acc: 0.7856 - val_loss: 0.6058 - val_acc: 0.8103\n",
      "Epoch 86/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6213 - acc: 0.7829 - val_loss: 0.6335 - val_acc: 0.8007\n",
      "Epoch 87/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6347 - acc: 0.7804 - val_loss: 0.6140 - val_acc: 0.8074\n",
      "Epoch 88/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6168 - acc: 0.7826 - val_loss: 0.6142 - val_acc: 0.8028\n",
      "Epoch 89/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.5960 - acc: 0.7903 - val_loss: 0.6070 - val_acc: 0.8019\n",
      "Epoch 90/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6399 - acc: 0.7810 - val_loss: 0.6152 - val_acc: 0.8003\n",
      "Epoch 91/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6076 - acc: 0.7854 - val_loss: 0.6121 - val_acc: 0.8036\n",
      "Epoch 92/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6172 - acc: 0.7855 - val_loss: 0.6191 - val_acc: 0.7940\n",
      "Epoch 93/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6187 - acc: 0.7893 - val_loss: 0.6088 - val_acc: 0.8070\n",
      "Epoch 94/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6176 - acc: 0.7840 - val_loss: 0.6330 - val_acc: 0.7986\n",
      "Epoch 95/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.6020 - acc: 0.7895 - val_loss: 0.5969 - val_acc: 0.8049\n",
      "Epoch 96/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.5867 - acc: 0.7975 - val_loss: 0.6191 - val_acc: 0.8023\n",
      "Epoch 97/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.5933 - acc: 0.7950 - val_loss: 0.6035 - val_acc: 0.8082\n",
      "Epoch 98/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.5731 - acc: 0.7982 - val_loss: 0.6234 - val_acc: 0.8019\n",
      "Epoch 99/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.5992 - acc: 0.7891 - val_loss: 0.6124 - val_acc: 0.8003\n",
      "Epoch 100/100\n",
      "9531/9531 [==============================] - 17s 2ms/step - loss: 0.5811 - acc: 0.8016 - val_loss: 0.6180 - val_acc: 0.8040\n",
      "9531/9531 [==============================] - 5s 501us/step\n",
      "Train Loss = 0.15298001966372252\n",
      "Train Accuracy = 0.959395656279509\n",
      "2383/2383 [==============================] - 1s 501us/step\n",
      "Test Loss = 0.6179565078462816\n",
      "Test Accuracy = 0.8040285355095297\n",
      "time: 1680.9465487003326\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "start = time.time()\n",
    "\n",
    "model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n",
    "\n",
    "history = LossHistory() # 创建一个history实例\n",
    "\n",
    "model.fit(X_train, Y_train, epochs=100, batch_size=64, verbose=1, \n",
    "            validation_data=(X_test, Y_test),callbacks=[history])\n",
    "\n",
    "preds_train = model.evaluate(X_train, Y_train)\n",
    "print(\"Train Loss = \" + str(preds_train[0]))\n",
    "print(\"Train Accuracy = \" + str(preds_train[1]))\n",
    "\n",
    "preds_test  = model.evaluate(X_test, Y_test)\n",
    "print(\"Test Loss = \" + str(preds_test[0]))\n",
    "print(\"Test Accuracy = \" + str(preds_test[1]))\n",
    "\n",
    "end = time.time()\n",
    "print(\"time:\",end-start)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f0eb84c7c50>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "history.loss_plot('epoch')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  },
  "toc": {
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": "block",
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
